#
# Copyright (c) 2010, Monash e-Research Centre
#	(Monash University, Australia)
# Copyright (c) 2010, VeRSI Consortium
#	(Victorian eResearch Strategic Initiative, Australia)
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#	 *	Redistributions of source code must retain the above copyright
#		notice, this list of conditions and the following disclaimer.
#	 *	Redistributions in binary form must reproduce the above copyright
#		notice, this list of conditions and the following disclaimer in the
#		documentation and/or other materials provided with the distribution.
#	 *	Neither the name of the VeRSI, the VeRSI Consortium members, nor the
#		names of its contributors may be used to endorse or promote products
#		derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
from django.template import Context, loader
from django.http import HttpResponse

from django.conf import settings

from django.shortcuts import render_to_response
from django.template import RequestContext
from django.contrib.auth import authenticate, login
from django.contrib.auth.models import User
from django.http import HttpResponseRedirect, HttpResponseForbidden, HttpResponseNotFound, HttpResponseServerError
from django.contrib.auth.decorators import login_required

from tardis.tardis_portal.ProcessExperiment import ProcessExperiment
from tardis.tardis_portal.SiteParser import SiteParser
from tardis.tardis_portal.SiteSettingsParser import SiteSettingsParser

from tardis.tardis_portal.RegisterExperimentForm import RegisterExperimentForm
from tardis.tardis_portal.NewParametersForm import NewParametersForm

from django.core.paginator import Paginator, InvalidPage, EmptyPage

from tardis.tardis_portal.models import *
from django.db.models import Sum

from tardis.tardis_portal.MultiPartForm import MultiPartForm

import urllib, urllib2

def render_response_index(request, *args, **kwargs):

	kwargs['context_instance'] = RequestContext(request)

	kwargs['context_instance']['is_authenticated'] = request.user.is_authenticated()
	
	if 'username' in request.session.keys():
		kwargs['context_instance']['username'] = request.session['username']
	else:
		kwargs['context_instance']['username'] = None
	
	#stats
	kwargs['context_instance']['public_datasets'] = Dataset.objects.filter()
	kwargs['context_instance']['public_datafiles'] = Dataset_File.objects.filter()
	kwargs['context_instance']['public_experiments'] = Experiment.objects.filter()

	# kwargs['context_instance']['public_datafiles_aggregate'] = kwargs['context_instance']['public_datafiles'].aggregate(Sum('size'))

	# size = 0
	# for df in kwargs['context_instance']['public_datafiles']:
	# 	size = size + long(df.size)
	# 
	try:
		s = open(settings.TMP_WRITE_DIR + 'size', 'r')
		kwargs['context_instance']['public_datafile_size'] = s.read()
	except:
		kwargs['context_instance']['public_datafile_size'] = 0

	# 
	# if kwargs['context_instance']['public_datasets'].count() > 0:
	#	kwargs['context_instance']['public_dataset_avg_size'] = kwargs['context_instance']['public_datafiles_aggregate']['size__sum'] / kwargs['context_instance']['public_datasets'].count()
	# else:
	#	kwargs['context_instance']['public_dataset_avg_size'] = 0
	
	return render_to_response(*args, **kwargs)
	
def return_response_error(request):
	c = Context({
		'status': "ERROR: Forbidden",
		'error': True		
	})

	return HttpResponseForbidden(render_response_index(request, 'tardis_portal/blank_status.html', c))
	
def return_response_not_found(request):
	c = Context({
		'status': "ERROR: Not Found",
		'error': True
	})

	return HttpResponseNotFound(render_response_index(request, 'tardis_portal/blank_status.html', c))	
	
def return_response_error_message(request, redirect_path, message):
	c = Context({
		'status': message,
		'error': True		
	})

	return HttpResponseServerError(render_response_index(request, redirect_path, c))	
	
#custom decorator
def synch_login_required(f):
		def wrap(request, *args, **kwargs):
				#this check the session if userid key exist, if not it will redirect to login page
				if 'username' not in request.session.keys():
						return HttpResponseRedirect("/login")
				return f(request, *args, **kwargs)
		wrap.__doc__=f.__doc__
		wrap.__name__=f.__name__
		return wrap

def authenticate_user(username, password):
	from suds.client import Client
	url = settings.VBLSTORAGEGATEWAY_URL
	client = Client(url)

	result = client.service.VBLgetExpIDs(username, password)

	if not result == None:
		if not result.find('Error') == -1:
			return False
		else:
			return True 
	else:
		return False
		
def get_expids(username, password):

	from suds.client import Client
	url = settings.VBLSTORAGEGATEWAY_URL
	client = Client(url)

	result = client.service.VBLgetExpIDs(username, password)
	
	expids = []
	
	if result.find('Error') == -1:
		for expid in result.split(','):
			expids.append(expid)

	return expids
	
def get_experiments_for_user(expids):
	# from stackoverflow question 852414
	from django.db.models import Q
	
	queries = [Q(expid=expid) for expid in expids]
	
	query = queries.pop()
	
	for item in queries:
		query |= item
		
	experiments = Experiment.objects.filter(query)
	
	return experiments
	
def get_datafiles_for_user(expids):

	# from stackoverflow question 852414
	from django.db.models import Q

	queries = [Q(dataset__experiment__expid=expid) for expid in expids]

	query = queries.pop()

	for item in queries:
		query |= item

	dataset_files = Dataset_File.objects.filter(query)

	return dataset_files	
	
def can_access_dataset(username, password, dataset_id):

	experiments = get_experiments_for_user(get_expids(username, password))

	experiments = experiments.filter(dataset__pk=dataset_id)
	
	if experiments.count() > 0:
		return True
	else:
		return False

def can_access_experiment(username, password, experiment_id):
	expid = Experiment.objects.get(pk=experiment_id).expid
	
	experiments = get_experiments_for_user(get_expids(username, password))
	experiments = experiments.filter(expid=expid)
	experiment = experiments.get(pk=experiment_id)
	
	if experiment:
		return experiment
	else:
		return False

@synch_login_required		
def display_dataset_image(request, dataset_id, parameterset_id, parameter_name):

	#todo handle not exist
	dataset = Dataset.objects.get(pk=dataset_id)
	if can_access_experiment(request.session['username'], request.session['password'], dataset.experiment.id):
		
		image = DatasetParameter.objects.get(name__name=parameter_name, parameterset=parameterset_id)

		import base64

		data = base64.b64decode(image.string_value)

		response = HttpResponse(data, mimetype='image/jpeg')

		return response
	else:
		return return_response_error(request)	

@synch_login_required
def display_datafile_image(request, dataset_file_id, parameterset_id, parameter_name):

	#todo handle not exist
	datafile = Dataset_File.objects.get(pk=dataset_file_id)
	if can_access_experiment(request.session['username'], request.session['password'], datafile.dataset.experiment.id):
		image = DatafileParameter.objects.get(name__name=parameter_name, parameterset=parameterset_id)

		import base64

		data = base64.b64decode(image.string_value)

		response = HttpResponse(data, mimetype='image/jpeg')

		return response
	else:
		return return_response_error(request)		

def login(request):
	
	#todo put me in SETTINGS
	from suds.client import Client
	url = settings.VBLSTORAGEGATEWAY_URL
	client = Client(url)
	
	if request.POST.has_key('username') and request.POST.has_key('password'):
		username = request.POST['username']
		password = request.POST['password']

		if not authenticate_user(username, password):
			return_response_error_message(request, "tardis_portal/index.html", "Sorry, username and password don't match")
		else:
			request.session['username'] = username
			request.session['password'] = password
			
			next = '/'
			if request.POST.has_key('next'):
				next = request.POST['next']
				
			c = Context({
			})				
			return HttpResponseRedirect(next)
			
	c = Context({
	})
	return HttpResponse(render_response_index(request, 'tardis_portal/login.html', c))			
	
def logout(request):
	try:
		del request.session['username']
		del request.session['password']
	except KeyError:
		pass
		
	c = Context({

	})		
	return HttpResponse(render_response_index(request, 'tardis_portal/index.html', c))	

def index(request):
	
	status = ""

	c = Context({
		'status': status,
	})
	return HttpResponse(render_response_index(request, 'tardis_portal/index.html', c))	

@synch_login_required
def download(request, id):
	
	from suds.client import Client
	
	import logging
	logging.basicConfig(level=logging.INFO)
	logging.getLogger('suds.client').setLevel(logging.DEBUG)
	
	url = settings.VBLSTORAGEGATEWAY_URL
	client = Client(url)	
	
	# security
	if request.GET.has_key('url') and len(request.GET['url']) > 0:
		print request.GET['url']
		if request.GET['url'].startswith('file://'):
			absolute_filename = request.GET['url'].partition('//')[2]
			
			fileString = absolute_filename + "\\r\\nTARDIS\\r\\n"

			key = client.service.VBLstartTransferSSL(request.session['username'], \
			request.session['password'], \
			request.GET['expid'],\
			fileString)
			
			# check existence of expid
			c = Context({
				'subtitle': "Download",
				'key': key,
				'expid': request.GET['expid'],
				'username': request.session['username'],
			})
			return HttpResponse(render_response_index(request, 'tardis_portal/download.html', c))			
		else:
			return HttpResponseRedirect(request.GET['url'])
	elif request.POST.has_key('datafile'):
		
		fileString = ""

		for datafile in request.POST.getlist('datafile'):
			absolute_filename = datafile.partition('//')[2]
			fileString = fileString + absolute_filename + "\\r\\nTARDIS\\r\\n"

		key = client.service.VBLstartTransferSSL(request.session['username'], \
		request.session['password'], \
		request.POST['expid'],\
		fileString) 
		
		c = Context({
			'subtitle': "Download",
			'key': key,
			'expid': request.POST['expid'],
			'username': request.session['username'],
		})
		return HttpResponse(render_response_index(request, 'tardis_portal/download.html', c))
	else:
		return return_response_error(request)
		
#todo merge with download view?
@synch_login_required
def downloadExperiment(request, eid):
	
	# datafiles = Dataset_File.objects.filter(dataset__experiment__pk=eid)
	# expid = datafile.dataset.experiment.expid
	# 
	# fileString = ""
	# for datafile in datafiles:
	#	url = datafile.url.partition('//')[2]
	#	fileString = fileString + '/' + url + "\\r\\nTARDIS\\r\\n"
	
	from suds.client import Client
	
	import logging
	logging.basicConfig(level=logging.INFO)
	logging.getLogger('suds.client').setLevel(logging.DEBUG)
	
	url = settings.VBLSTORAGEGATEWAY_URL
	client = Client(url)	
	
	experiment = Experiment.objects.get(pk=eid)
	expid = experiment.expid
	
	key = client.service.VBLstartTransferSSL(request.session['username'], \
	request.session['password'], \
	expid,\
	'')
	
	# check existence of expid
	c = Context({
		'subtitle': "Download",
		'key': key,
		'expid': expid,
		'username': request.session['username'],
	})
	return HttpResponse(render_response_index(request, 'tardis_portal/download.html', c))	

def about(request):
	
	c = Context({
		'subtitle': "About",
	})
	return HttpResponse(render_response_index(request, 'tardis_portal/about.html', c))	

def help(request):

	c = Context({
		'subtitle': "Help",
	})
	return HttpResponse(render_response_index(request, 'tardis_portal/help.html', c))	
	
@synch_login_required
def view_experiment(request, experiment_id):
	
	try:
		experiment = can_access_experiment(request.session['username'], request.session['password'], experiment_id)
		if experiment:
			author_experiments = Author_Experiment.objects.all()
			author_experiments = author_experiments.filter(experiment=experiment)
			author_experiments = author_experiments.order_by('order')
		
			datafiles = Dataset_File.objects.filter(dataset__experiment=experiment_id)
	
			c = Context({
			'experiment': experiment,
			'authors': author_experiments,
			'datafiles': datafiles,		
			'subtitle': experiment.title,			
			})
		else:
			return return_response_not_found(request)
	except Experiment.DoesNotExist, de:
		return return_response_not_found(request)
	
	return HttpResponse(render_response_index(request, 'tardis_portal/view_experiment.html', c))

@synch_login_required
def experiment_index(request):
	
	experiments = get_experiments_for_user(get_expids(request.session['username'], request.session['password']))
	experiments = experiments.order_by('title')

	c = Context({
	'experiments': experiments,
	'subtitle': "Experiment Index",
	})
	return HttpResponse(render_response_index(request, 'tardis_portal/experiment_index.html', c))

def create_placeholder_experiment(user, expid):
	print "expid = " + expid
	
	e = Experiment(url=SafeUnicode('http://www.example.com'), approved=True, private_password=None , \
	title=SafeUnicode("Placeholder Title"), institution_name=SafeUnicode("Placeholder"), \
	description=SafeUnicode("Placeholder description"), created_by=user.id, expid=str(expid))

	e.save()

	return e.id

# web service
def register_experiment_ws_xmldata(request):
	import sys
	import threading

	process_experiment = ProcessExperiment()
	status = ""
	if request.method == 'POST': # If the form has been submitted...

		form = RegisterExperimentForm(request.POST, request.FILES) # A form bound to the POST data
		if form.is_valid(): # All validation rules pass

			xmldata = request.FILES['xmldata']
			username = form.cleaned_data['username']
			password = form.cleaned_data['password']
			expid = form.cleaned_data['expid']
			experiment_owner = form.cleaned_data['experiment_owner']
			
			from django.contrib.auth import authenticate
			user = authenticate(username=username, password=password)
			if user is not None:
				if not user.is_active:
					return return_response_error(request)
			else:
				return return_response_error(request)		
				
			# try:
			# 	experiment = Experiment.objects.get(expid=expid)
			# 	print "experiment id " + expid + "already exists"
			# 	return return_response_error(request)				
			# except Experiment.DoesNotExist, de:
			# 	pass

			eid = create_placeholder_experiment(user, expid)			

			# todo this entire function needs a fancy class with functions for each part..
			import os
			
			f = open(settings.TMP_WRITE_DIR + str(eid), "w")

			for chunk in xmldata.chunks():
				f.write(chunk)
				
			filename = f.name	
			
			f.close()
			
			experiment_owners = experiment_owner.split('#')
			
			if not len(experiment_owners) == 0:

				sp = SiteParser(settings.MYTARDIS_SITES_URL, settings.MYTARDIS_SITES_USERNAME, settings.MYTARDIS_SITES_PASSWORD)

				for name in sp.getSiteNames():
					url = sp.getSiteSettingsURL(name)
					
					print url + " " + sp.getSiteSettingsUsername(name) + " " + sp.getSiteSettingsPassword(name)

					ssp = SiteSettingsParser(url, sp.getSiteSettingsUsername(name), sp.getSiteSettingsPassword(name))
					
					###
					# Create the form with simple fields
					mpform = MultiPartForm()
					mpform.add_field('username', ssp.getRegisterSetting('username'))
					mpform.add_field('password', ssp.getRegisterSetting('password'))
					mpform.add_field('from_url', settings.TARDISURLPREFIX)
					mpform.add_field('originid', str(eid))			

					f = open(filename, "r")
					# Add a fake file
					mpform.add_file('xmldata', 'METS.xml', 
								  fileHandle=f)									
				
					siteOwners = list()
					for owner in experiment_owners:
						print "experiment owner: " + owner	
						for ends_with in ssp.getEmailEndswith():
							if owner.endswith(ends_with):
								siteOwners.append(owner)
						
					if siteOwners:
					
						for siteOwner in siteOwners:
							mpform.add_field('experiment_owner', urllib.quote_plus(siteOwner))
					
						# import socket
						# socket.setdefaulttimeout(1000000)
					
						print "about to send register request to site"
						# Build the request
						requestmp = urllib2.Request(ssp.getRegisterSetting('url'))
						requestmp.add_header('User-agent', 'PyMOTW (http://www.doughellmann.com/PyMOTW/)')
						body = str(mpform)
						requestmp.add_header('Content-type', mpform.get_content_type())
						requestmp.add_header('Content-length', len(body))
						requestmp.add_data(body)

						print
						print 'OUTGOING DATA:'
						# print requestmp.get_data()

						print
						print 'SERVER RESPONSE:'
						print urllib2.urlopen(requestmp).read() 
						###		
						print "finished register request to site"
						
			print "about to locally authenticate before registering"
			from django.contrib.auth import authenticate
			user = authenticate(username=username, password=password)
			if user is not None:
				if not user.is_active:
					return return_response_error(request)
			else:
				return return_response_error(request)		

			print "about to process experiment"
			process_experiment.register_experiment_xmldata_file(filename=filename, created_by=user.username, eid=eid, expid=expid)
			print "finished registering locally, about to return a response"
			
			response = HttpResponse('Finished cataloging: ' + str(eid), status=200)
			response['Location'] = settings.TARDISURLPREFIX + "/experiment/view/" + str(eid)

			return response						

	else:
		form = RegisterExperimentForm() # An unbound form

	c = Context({
		'form': form,
		'status': status,
		'subtitle': "Register Experiment",
	})
	return HttpResponse(render_response_index(request, 'tardis_portal/register_experiment.html', c))

def file_transfer(request):

	#todo handle missing
	#todo more than just ip locking security..
	print "transfer method evoked.."
	if request.method == 'POST':
		originid = request.POST['originid']
		eid = request.POST['eid']
		site_settings_url = request.POST['site_settings_url']
		username = request.POST['username']
		password = request.POST['password']
		
		print username + " " + site_settings_url
		
		expid = Experiment.objects.get(pk=originid).expid
		ssp = SiteSettingsParser(site_settings_url, username, password) 
		
		from suds.client import Client

		import logging
		logging.basicConfig(level=logging.INFO)
		logging.getLogger('suds.client').setLevel(logging.DEBUG)

		url = settings.VBLSTORAGEGATEWAY_URL
		client = Client(url, cache=None)
		x509 = ssp.getTransferSetting('password')
		
		print x509
		print expid			
		
		print client
		
		# todo: support other protocols
		# todo: make into function
		try:
			key = client.service.VBLstartTransferGridFTP( \
			ssp.getTransferSetting('user'), \
			x509, \
			expid,\
			'/Frames\\r\\nTARDIS\\r\\n',\
			ssp.getTransferSetting('sl'),\
			ssp.getTransferSetting('serversite') + eid + '/',\
			ssp.getTransferSetting('optionFast'),\
			ssp.getTransferSetting('optionPenable'),\
			ssp.getTransferSetting('optionP'),\
			ssp.getTransferSetting('optionBSenable'),\
			ssp.getTransferSetting('optionBS'),\
			ssp.getTransferSetting('optionTCPBenable'),\
			ssp.getTransferSetting('optionTCPBS')\
			)
		except URLError, e:
			try:			
				key = client.service.VBLstartTransferGridFTP( \
				ssp.getTransferSetting('user'), \
				x509, \
				expid,\
				'/Frames\\r\\nTARDIS\\r\\n',\
				ssp.getTransferSetting('sl'),\
				ssp.getTransferSetting('serversite') + eid + '/',\
				ssp.getTransferSetting('optionFast'),\
				ssp.getTransferSetting('optionPenable'),\
				ssp.getTransferSetting('optionP'),\
				ssp.getTransferSetting('optionBSenable'),\
				ssp.getTransferSetting('optionBS'),\
				ssp.getTransferSetting('optionTCPBenable'),\
				ssp.getTransferSetting('optionTCPBS')\
				)	
			except URLError, e:
				key = client.service.VBLstartTransferGridFTP( \
				ssp.getTransferSetting('user'), \
				x509, \
				expid,\
				'/Frames\\r\\nTARDIS\\r\\n',\
				ssp.getTransferSetting('sl'),\
				ssp.getTransferSetting('serversite') + eid + '/',\
				ssp.getTransferSetting('optionFast'),\
				ssp.getTransferSetting('optionPenable'),\
				ssp.getTransferSetting('optionP'),\
				ssp.getTransferSetting('optionBSenable'),\
				ssp.getTransferSetting('optionBS'),\
				ssp.getTransferSetting('optionTCPBenable'),\
				ssp.getTransferSetting('optionTCPBS')\
				)				
				
	response = HttpResponse('OK', status=200)
	return response 

@synch_login_required
def register_experiment(request):

	# from java.lang import Exception
	import sys

	process_experiment = ProcessExperiment()
	status = ""
	if request.method == 'POST': # If the form has been submitted...
		form = RegisterExperimentForm(request.POST) # A form bound to the POST data
		if form.is_valid(): # All validation rules pass

			url = form.cleaned_data['url']
			private_password = form.cleaned_data['private_password']			

				# try:
			process_experiment.register_experiment(url=url, created_by=request.user, private_password=private_password)
					#				except IOError, i:
					#					return return_response_error_message(request, 'tardis_portal/blank_status.html', "Error reading file. Perhaps an incorrect URL?")				
					#				except:
					#					return return_response_error_message(request, 'tardis_portal/blank_status.html', "Unexpected Error - ", sys.exc_info()[0])				

		status = "Experiment successfully registered. Experiment must be approved " \
		"by an administrator before being made public."

		c = Context({
			'title': "Register Experiment",
			'status': status,
			'subtitle': "Register Experiment",
		})
		return HttpResponse(render_response_index(request, 'tardis_portal/blank_status.html', c))								

		status = "Experiment successfully reingested."			

	else:
		form = RegisterExperimentForm() # An unbound form

	c = Context({
		'form': form,
		'status': status,
		'subtitle': "Register Experiment",
	})
	return HttpResponse(render_response_index(request, 'tardis_portal/register_experiment.html', c))

@synch_login_required
def retrieve_parameters(request, dataset_file_id):

	parametersets = DatafileParameterSet.objects.all()
	parametersets = parametersets.filter(dataset_file__pk=dataset_file_id)

	c = Context({
		'parametersets': parametersets,
	})

	return HttpResponse(render_response_index(request, 'tardis_portal/ajax/parameters.html', c))	

@synch_login_required
def retrieve_xml_data(request, dataset_file_id):
	from pygments import highlight
	from pygments.lexers import XmlLexer
	from pygments.formatters import HtmlFormatter
	from pygments.styles import get_style_by_name

	xml_data = XML_data.objects.get(datafile__pk=dataset_file_id)

	formatted_xml = highlight(xml_data.data, XmlLexer(), HtmlFormatter(style='default', noclasses=True))	

	c = Context({
		'formatted_xml': formatted_xml,
	})
	return HttpResponse(render_response_index(request, 'tardis_portal/ajax/xml_data.html', c))	

@synch_login_required		
def retrieve_datafile_list(request, dataset_id):
	from django.db.models import Count

	if can_access_dataset(request.session['username'], request.session['password'], dataset_id):
		dataset_results = Dataset_File.objects.filter(dataset__pk=dataset_id).order_by('filename')

		filename_search = None

		if request.GET.has_key('filename') and len(request.GET['filename']) > 0:
			filename_search = request.GET['filename']
			dataset_results = dataset_results.filter(url__icontains=filename_search)

		paginator = Paginator(dataset_results, 500)

		try:
			page = int(request.GET.get('page', '1'))
		except ValueError:
			page = 1

		# If page request (9999) is out of range, deliver last page of results.
		try:
			dataset = paginator.page(page)
		except (EmptyPage, InvalidPage):
			dataset = paginator.page(paginator.num_pages)

		c = Context({
			'dataset': dataset,
			'paginator': paginator,
			'dataset_id': dataset_id,
			'filename_search': filename_search,
		})
		return HttpResponse(render_response_index(request, 'tardis_portal/ajax/datafile_list.html', c))	
	else:
		return return_response_not_found(request)	

@synch_login_required
def search_experiment(request):
	get = False
	experiments = get_experiments_for_user(get_expids(request.session['username'], request.session['password']))
	experiments = experiments.order_by('title')

	if request.GET.has_key('results'):
		get = True
		if request.GET.has_key('title') and len(request.GET['title']) > 0:
			experiments = experiments.filter(title__icontains=request.GET['title'])

		if request.GET.has_key('description') and len(request.GET['description']) > 0:
			experiments = experiments.filter(description__icontains=request.GET['description'])

		if request.GET.has_key('institution_name') and len(request.GET['institution_name']) > 0:
			experiments = experiments.filter(institution_name__icontains=request.GET['institution_name'])

		if request.GET.has_key('creator') and len(request.GET['creator']) > 0:
			experiments = experiments.filter(author_experiment__author__name__icontains=request.GET['creator'])

	c = Context({
		'submitted': get,
		'experiments': experiments,
		'subtitle': "Search Experiments",
	})
	return HttpResponse(render_response_index(request, 'tardis_portal/search_experiment.html', c))
	
@synch_login_required
def search_datafile(request):
	get = False 
	
	datafile_results = get_datafiles_for_user(get_expids(request.session['username'], request.session['password']))

	datafile_results = datafile_results.order_by('filename')

	if request.GET.has_key('results'):
		get = True
		if request.GET.has_key('filename') and len(request.GET['filename']) > 0:
			datafile_results = datafile_results.filter(filename__icontains=request.GET['filename'])

		if request.GET.has_key('diffractometerType') and request.GET['diffractometerType'] != '-':
			datafile_results = datafile_results.filter(dataset__datasetparameterset__datasetparameter__name__name__icontains='diffractometerType', \
			dataset__datasetparameterset__datasetparameter__string_value__icontains=request.GET['diffractometerType'])
			
		if request.GET.has_key('xraySource') and len(request.GET['xraySource']) > 0:
			datafile_results = datafile_results.filter(dataset__datasetparameterset__datasetparameter__name__name__icontains='xraySource', \
			dataset__datasetparameterset__datasetparameter__string_value__icontains=request.GET['xraySource'])			
		
		if request.GET.has_key('crystalName') and len(request.GET['crystalName']) > 0:
			datafile_results = datafile_results.filter(dataset__datasetparameterset__datasetparameter__name__name__icontains='crystalName', \
			dataset__datasetparameterset__datasetparameter__string_value__icontains=request.GET['crystalName'])			

		if request.GET.has_key('resLimitTo') and len(request.GET['resLimitTo']) > 0:
			datafile_results = datafile_results.filter(dataset__datasetparameterset__datasetparameter__name__name__icontains='resolutionLimit', \
			dataset__datasetparameterset__datasetparameter__numerical_value__lte=request.GET['resLimitTo'])

		if request.GET.has_key('xrayWavelengthFrom') and len(request.GET['xrayWavelengthFrom']) > 0 and request.GET.has_key('xrayWavelengthTo') and len(request.GET['xrayWavelengthTo']) > 0:
			datafile_results = datafile_results.filter(datafileparameterset__datafileparameter__name__name__icontains='xrayWavelength', \
			datafileparameterset__datafileparameter__numerical_value__range=(request.GET['xrayWavelengthFrom'], \
			request.GET['xrayWavelengthTo']))	
			
	paginator = Paginator(datafile_results, 25) 
		
	try:
		page = int(request.GET.get('page', '1'))
	except ValueError:
		page = 1

	# If page request (9999) is out of range, deliver last page of results.
	try:
		datafiles = paginator.page(page)
	except (EmptyPage, InvalidPage):
		datafiles = paginator.page(paginator.num_pages)
				
	c = Context({
		'submitted': get,
		'datafiles': datafiles,
		'paginator': paginator,
		'query_string': request.META['QUERY_STRING'],
		'subtitle': "Search Datafiles",
	})
	return HttpResponse(render_response_index(request, 'tardis_portal/search_datafile.html', c))

def new_params(request):
	if request.method == 'POST': # If the form has been submitted...
		print "POSTed form"
		#form = NewParametersForm(request.POST) # A form bound to the POST data
			
		username = request.POST['username']
		password = request.POST['password']
		xml_prefix = request.POST['xml_prefix']
		schema = request.POST['schema']
		parameter_name = request.POST.getlist('parameter_name')
		full_name = request.POST.getlist('full_name')
		units = request.POST.getlist('units')
		is_numeric = request.POST.getlist('is_numeric')
		
		from django.contrib.auth import authenticate
		user = authenticate(username=username, password=password)
		if user is not None:
			if not user.is_active:
				return return_response_error(request)
		else:
			return return_response_error(request)
		
		#todo: nested entries
		pre = xml_prefix
		export = pre + '\n'
		export = export + schema + '\n'
		sample_xml = "<" + pre + ':metadata xmlns:' + pre + '="' + schema + '">' + '\n'
		schema_db = Schema(namespace=schema)
		schema_db.save()
		
		for i in map(None, parameter_name, full_name, units, is_numeric):
			if i[0] != '':
				
				is_numeric = False
				data = 'data'
				if i[3] == 'on':
					is_numeric = True
					data = '0'
				
				pn = ParameterName(schema=schema_db, name=i[0], full_name=i[1], units=i[2], is_numeric=is_numeric)
				pn.save()
				
				sample_xml = sample_xml + '		<' + pre + ':' + i[0] + '>' + data + '</' + pre + ':' + i[0] + '>' + '\n'
				export = export + i[0] + '^' + i[1] + '^' + i[2] + '^' + str(is_numeric) + '\n'
				
		sample_xml = sample_xml + '</' + pre + ':metadata>'
				
		c = Context({
			'sample_xml': sample_xml,
			'export': export,
			'post': True,
		})
		return HttpResponse(render_response_index(request, 'tardis_portal/new_params.html', c))
					
	else:
		form = RegisterExperimentForm() # An unbound form

		c = Context({
			'form': form,
			'num_display_params': range(100),
		})
		return HttpResponse(render_response_index(request, 'tardis_portal/new_params.html', c))			

def totaldatasize(request):
	# runs on a cron job (hey mike) and calculates the data size
	
	size = 0
	for df in Dataset_File.objects.filter():
		size = size + long(df.size)
	
	f = open(settings.TMP_WRITE_DIR + 'size', 'w')
	
	f.write(str(size))
	
	return HttpResponse('OK')